package com.tind.wyf.baselib.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;


import com.tind.wyf.baselib.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter {

        protected List<T> mItems;
        protected Context mContext;
        protected LayoutInflater mInflater;

        protected String mSystemTime;

        protected int mSelectedPosition = -0;
        public static final int STATE_NO_MORE = 1;
        public static final int STATE_LOAD_MORE = 2;
        public static final int STATE_INVALID_NETWORK = 3;
        public static final int STATE_HIDE = 5;
        private static final int STATE_REFRESHING = 6;
        public static final int STATE_LOAD_ERROR = 7;
        public static final int STATE_LOADING = 8;
        public static final int STATE_LOAD = 9;

        private final int BEHAVIOR_MODE;
        protected int mState;

        public static final int NEITHER = 0;
        public static final int ONLY_HEADER = 1;
        public static final int ONLY_FOOTER = 2;
        public static final int BOTH_HEADER_FOOTER = 3;

        protected static final int VIEW_TYPE_NORMAL = 0;
        private static final int VIEW_TYPE_HEADER = -1;
        private static final int VIEW_TYPE_FOOTER = -2;

        private OnItemClickListener onItemClickListener;
        private OnItemLongClickListener onItemLongClickListener;

        private OnClickListener onClickListener;
        private OnLongClickListener onLongClickListener;


        protected View mHeaderView;

        private OnLoadingHeaderCallBack onLoadingHeaderCallBack;

        public BaseRecyclerAdapter(Context context, int mode) {
            mItems = new ArrayList<>();
            this.mContext = context;
            this.mInflater = LayoutInflater.from(context);
            BEHAVIOR_MODE = mode;
            mState = STATE_HIDE;
            initListener();
        }

        /**
         * 初始化listener
         */
        private void initListener() {
            onClickListener = new OnClickListener() {
                @Override
                public void onClick(int position, long itemId) {
                    if (onItemClickListener != null)
                        onItemClickListener.onItemClick(position, itemId);
                }
            };

            onLongClickListener = new OnLongClickListener() {
                @Override
                public boolean onLongClick(int position, long itemId) {
                    if (onItemLongClickListener != null) {
                        onItemLongClickListener.onLongClick(position, itemId);
                        return true;
                    }
                    return false;
                }
            };
        }

        public void setSystemTime(String systemTime) {
            this.mSystemTime = systemTime;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            switch (viewType) {
                case VIEW_TYPE_HEADER:
                    if (onLoadingHeaderCallBack != null)
                        return onLoadingHeaderCallBack.onCreateHeaderHolder(parent);
                    else
                        throw new IllegalArgumentException("you have to impl the interface when using this viewType");
                case VIEW_TYPE_FOOTER:
                    return new FooterViewHolder(mInflater.inflate(R.layout.recycler_footer_view, parent, false));
                default:
                    final RecyclerView.ViewHolder holder = onCreateDefaultViewHolder(parent, viewType);
                    if (holder != null) {
                        holder.itemView.setTag(holder);
                        holder.itemView.setOnLongClickListener(onLongClickListener);
                        holder.itemView.setOnClickListener(onClickListener);
                        onBindClickListener(holder);
                    }
                    return holder;
            }
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            switch (holder.getItemViewType()) {
                case VIEW_TYPE_HEADER:
                    if (onLoadingHeaderCallBack != null)
                        onLoadingHeaderCallBack.onBindHeaderHolder(holder, position);
                    break;
                case VIEW_TYPE_FOOTER:
                    FooterViewHolder fvh = (FooterViewHolder) holder;
                    fvh.itemView.setVisibility(View.VISIBLE);
                    switch (mState) {
                        case STATE_INVALID_NETWORK:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_network_error));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_LOAD_MORE:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_load));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_LOADING:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_loading));
                            fvh.pb_footer.setVisibility(View.VISIBLE);
                            break;
                        case STATE_NO_MORE:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_not_more));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_REFRESHING:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_refreshing));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_LOAD_ERROR:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_load_error));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_LOAD:
                            fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_load));
                            fvh.pb_footer.setVisibility(View.GONE);
                            break;
                        case STATE_HIDE:
                            fvh.itemView.setVisibility(View.GONE);
                            break;
                    }
                    break;
                default:
                    onBindDefaultViewHolder(holder, getItems().get(getIndex(position)), position);
                    break;
            }
        }

        protected void onBindClickListener(RecyclerView.ViewHolder holder) {

        }

        /**
         * 当添加到RecyclerView时获取GridLayoutManager布局管理器，修正header和footer显示整行
         *
         * @param recyclerView the mRecyclerView
         */
        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
            if (manager instanceof GridLayoutManager) {
                final GridLayoutManager gridManager = ((GridLayoutManager) manager);
                gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        return getItemViewType(position) == VIEW_TYPE_HEADER || getItemViewType(position) == VIEW_TYPE_FOOTER
                                ? gridManager.getSpanCount() : 1;
                    }
                });
            }
        }

        /**
         * 当RecyclerView在windows活动时获取StaggeredGridLayoutManager布局管理器，修正header和footer显示整行
         *
         * @param holder the RecyclerView.ViewHolder
         */
        @Override
        public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
                if (BEHAVIOR_MODE == ONLY_HEADER) {
                    p.setFullSpan(holder.getLayoutPosition() == 0);
                } else if (BEHAVIOR_MODE == ONLY_FOOTER) {
                    p.setFullSpan(holder.getLayoutPosition() == mItems.size() + 1);
                } else if (BEHAVIOR_MODE == BOTH_HEADER_FOOTER) {
                    if (holder.getLayoutPosition() == 0 || holder.getLayoutPosition() == mItems.size() + 1) {
                        p.setFullSpan(true);
                    }
                }
            }
        }

        @Override
        public int getItemViewType(int position) {
            if (position == 0 && (BEHAVIOR_MODE == ONLY_HEADER || BEHAVIOR_MODE == BOTH_HEADER_FOOTER))
                return VIEW_TYPE_HEADER;
            if (position + 1 == getItemCount() && (BEHAVIOR_MODE == ONLY_FOOTER || BEHAVIOR_MODE == BOTH_HEADER_FOOTER))
                return VIEW_TYPE_FOOTER;
            else return VIEW_TYPE_NORMAL;
        }


        public T getSelectedItem() {
            if (mSelectedPosition < 0 || mSelectedPosition >= mItems.size())
                return null;
            return mItems.get(mSelectedPosition);
        }


        /**
         * 单选
         */
        public void setSelectedPosition(int selectedPosition) {
            if (selectedPosition != mSelectedPosition) {
                updateItem(mSelectedPosition);
                mSelectedPosition = selectedPosition;
                updateItem(mSelectedPosition);
            }
            this.mSelectedPosition = selectedPosition;
            updateItem(selectedPosition);
        }

        protected int getIndex(int position) {
            return BEHAVIOR_MODE == ONLY_HEADER || BEHAVIOR_MODE == BOTH_HEADER_FOOTER ? position - 1 : position;
        }

        @Override
        public int getItemCount() {
            if (BEHAVIOR_MODE == ONLY_FOOTER || BEHAVIOR_MODE == ONLY_HEADER) {
                return mItems.size() + 1;
            } else if (BEHAVIOR_MODE == BOTH_HEADER_FOOTER) {
                return mItems.size() + 2;
            } else return mItems.size();
        }

        public int getCount() {
            return mItems.size();
        }

        protected abstract RecyclerView.ViewHolder onCreateDefaultViewHolder(ViewGroup parent, int type);

        protected abstract void onBindDefaultViewHolder(RecyclerView.ViewHolder holder, T item, int position);

        public final View getHeaderView() {
            return this.mHeaderView;
        }

        public final void setHeaderView(View view) {
            this.mHeaderView = view;
        }

        public final List<T> getItems() {
            return mItems;
        }

        public void addAll(List<T> items) {
            if (items != null) {
                this.mItems.addAll(items);
                notifyItemRangeInserted(this.mItems.size(), items.size());
            }
        }

        public final void addItem(T item) {
            if (item != null) {
                this.mItems.add(item);
                notifyItemChanged(mItems.size());
            }
        }


        public void addItem(int position, T item) {
            if (item != null) {
                this.mItems.add(getIndex(position), item);
                notifyItemInserted(position);
            }
        }

        public void replaceItem(int position, T item) {
            if (item != null) {
                this.mItems.set(getIndex(position), item);
                notifyItemChanged(position);
            }
        }

        public void updateItem(int position) {
            if (getItemCount() > position) {
                notifyItemChanged(position);
            }
        }


        public final void removeItem(T item) {
            if (this.mItems.contains(item)) {
                int position = mItems.indexOf(item);
                this.mItems.remove(item);
                notifyItemRemoved(position);
            }
        }

        public final void removeItem(int position) {
            if (this.getItemCount() > position) {
                this.mItems.remove(getIndex(position));
                notifyItemRemoved(position);
            }
        }

        public void moveItem(int fromPosition, int toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mItems, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mItems, i, i - 1);
                }
            }
            notifyItemMoved(fromPosition, toPosition);
        }

        public final T getItem(int position) {
            int p = getIndex(position);
            if (p < 0 || p >= mItems.size())
                return null;
            return mItems.get(getIndex(position));
        }

        public final void resetItem(List<T> items) {
            if (items != null) {
                clear();
                addAll(items);
            }
        }

        public final void clear() {
            this.mItems.clear();
            setState(STATE_HIDE, false);
            notifyDataSetChanged();
        }

        public void setState(int mState, boolean isUpdate) {
            this.mState = mState;
            if (isUpdate)
                updateItem(getItemCount() - 1);
        }

        public int getState() {
            return mState;
        }

        /**
         * 添加项点击事件
         *
         * @param onItemClickListener the RecyclerView item click listener
         */
        public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
        }

        /**
         * 添加项点长击事件
         *
         * @param onItemLongClickListener the RecyclerView item long click listener
         */
        public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
            this.onItemLongClickListener = onItemLongClickListener;
        }

        protected void setOnLoadingHeaderCallBack(OnLoadingHeaderCallBack listener) {
            onLoadingHeaderCallBack = listener;
        }


        /**
         * 可以共用同一个listener，相对高效
         */
        public static abstract class OnClickListener implements View.OnClickListener {
            @Override
            public void onClick(View v) {
                RecyclerView.ViewHolder holder = (RecyclerView.ViewHolder) v.getTag();
                onClick(holder.getAdapterPosition(), holder.getItemId());
            }

            public abstract void onClick(int position, long itemId);
        }

        /**
         * 点击事件
         */
        public static abstract class OnViewClickListener implements View.OnClickListener {
            @Override
            public void onClick(View v) {
                RecyclerView.ViewHolder holder = (RecyclerView.ViewHolder) v.getTag();
                onClick(v, holder.getAdapterPosition());
            }

            public abstract void onClick(View view, int position);
        }


        /**
         * 可以共用同一个listener，相对高效
         */
        public static abstract class OnLongClickListener implements View.OnLongClickListener {
            @Override
            public boolean onLongClick(View v) {
                RecyclerView.ViewHolder holder = (RecyclerView.ViewHolder) v.getTag();
                return onLongClick(holder.getAdapterPosition(), holder.getItemId());
            }

            public abstract boolean onLongClick(int position, long itemId);
        }


        /**
         *
         */
        public interface OnItemClickListener {
            void onItemClick(int position, long itemId);
        }


        public interface OnItemLongClickListener {
            void onLongClick(int position, long itemId);
        }

        /**
         * for load header view
         */
        public interface OnLoadingHeaderCallBack {
            RecyclerView.ViewHolder onCreateHeaderHolder(ViewGroup parent);

            void onBindHeaderHolder(RecyclerView.ViewHolder holder, int position);
        }

        public static class FooterViewHolder extends RecyclerView.ViewHolder {
            ProgressBar pb_footer;
            TextView tv_footer;

            FooterViewHolder(View view) {
                super(view);
                pb_footer = (ProgressBar) view.findViewById(R.id.pb_footer);
                tv_footer = (TextView) view.findViewById(R.id.tv_footer);
            }
        }

        public class HeaderViewHolder extends RecyclerView.ViewHolder {
            public HeaderViewHolder(View itemView) {
                super(itemView);
            }
        }

}
